package com.itjin.controller;

import com.itjin.model.domain.dto.ResetPasswordDTO;
import com.itjin.model.domain.dto.UpdateUserTagsDTO;
import com.itjin.model.domain.dto.UserLoginDTO;
import com.itjin.model.domain.dto.UserRegisterDTO;
import com.itjin.model.domain.entity.User;
import com.itjin.model.domain.vo.UserLoginVO;
import com.itjin.model.domain.vo.UserRegisterVO;
import com.itjin.model.domain.vo.UserStatsVO;
import com.itjin.model.domain.vo.UserVO;
import com.itjin.model.result.Result;
import com.itjin.service.UserService;
import com.itjin.utils.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import jakarta.annotation.Resource;
import java.util.List;

/**
 * 用户接口
 */
@RestController
@RequestMapping("/user")
@Tag(name = "用户控制器")
@Slf4j
public class UserController {

    @Resource
    private UserService userService;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @PostMapping("/register")
    @Operation(summary = "用户注册")
    public Result<UserRegisterVO> userRegister(@RequestBody UserRegisterDTO userRegisterDTO) {
        if (userRegisterDTO == null) {
            return Result.failure(400, "账号或密码不完整");
        }
        String userAccount = userRegisterDTO.getUserAccount();
        String email = userRegisterDTO.getEmail();
        String captcha = userRegisterDTO.getCaptcha();
        String userPassword = userRegisterDTO.getUserPassword();
        String checkPassword = userRegisterDTO.getCheckPassword();
        if (StringUtils.isAllBlank(userAccount, userPassword, checkPassword, email, captcha)) {
            return Result.failure(400, "账号或密码不完整");
        }
        return userService.userRegister(userAccount, email, captcha, userPassword, checkPassword);

    }

    @PostMapping("/login")
    @Operation(summary = "用户登录")
    public Result<UserLoginVO> userLogin(@RequestBody UserLoginDTO userLoginDTO) {
        if (userLoginDTO == null) {
            return Result.failure(400, "账号/邮箱或密码不完整");
        }
        String loginIdentifier = userLoginDTO.getUserAccount();
        String userPassword = userLoginDTO.getUserPassword();

        if (StringUtils.isAllBlank(loginIdentifier, userPassword)) {
            return Result.failure(400, "账号/邮箱或密码不完整");
        }

        User user = userService.userLogin(loginIdentifier, userPassword);
        // 添加日志
        log.debug("登录用户信息: {}", user);

        // 生成包含角色信息的JWT
        String token = JwtUtil.generateToken(user.getUserAccount(), user.getUserRole());

        // 构建返回对象
        UserLoginVO loginVO = UserLoginVO.builder()
                .id(user.getId())
                .userAccount(user.getUserAccount())
                .username(user.getUsername())
                .userRole(user.getUserRole())
                .token(token)
                .avatar(user.getAvatar())
                .gender(user.getGender())
                .phone(user.getPhone())
                .email(user.getEmail())
                .tags(user.getTags())
                .userStatus(user.getUserStatus())
                .createTime(user.getCreateTime())
                .updateTime(user.getUpdateTime())
                .biography(user.getBiography())
                .build();

        // 添加日志
        log.debug("返回给前端的用户信息: {}", loginVO);

        return Result.success(loginVO);
    }

    /**
     * 获取用户统计数据
     * 
     * @param userId 用户ID
     * @return 用户统计数据
     */
    @GetMapping("/query/{userId}")
    @Operation(summary = "获取用户统计数据")
    public Result<UserStatsVO> getUserStats(@PathVariable Integer userId) {
        try {
            // 1. 参数校验
            if (userId == null || userId <= 0) {
                return Result.failure(400, "用户ID不合法");
            }

            // 2. 查询用户
            User user = userService.getById(userId);
            if (user == null || user.getIsDelete() == 1) {
                return Result.failure(404, "用户不存在");
            }

            // 3. 构建返回数据
            UserStatsVO statsVO = UserStatsVO.builder()
                    .myFollows(user.getMyFollows())
                    .myFans(user.getMyFans())
                    .myPublish(user.getMyPublish())
                    .myPraised(user.getMyPraised())
                    .myCollection(user.getMyCollection())
                    .build();

            return Result.success(statsVO);

        } catch (Exception e) {
            log.error("获取用户统计数据失败: {}", e.getMessage());
            return Result.failure(500, "获取用户统计数据失败");
        }
    }

    /**
     * 获取用户详细信息
     * 
     * @param userId 用户ID
     * @return 用户详细信息
     */
    @GetMapping("/info/{userId}")
    @Operation(summary = "获取用户详细信息")
    public Result<UserVO> getUserInfo(@PathVariable("userId") Integer userId) {
        try {
            // 1. 参数校验
            if (userId == null || userId <= 0) {
                return Result.failure(400, "用户ID不合法");
            }

            // 2. 查询用户
            User user = userService.getById(userId);
            if (user == null || user.getIsDelete() == 1) {
                return Result.failure(404, "用户不存在");
            }

            // 3. 转换为VO对象
            UserVO userVO = UserVO.builder()
                    .id(user.getId())
                    .userAccount(user.getUserAccount())
                    .username(user.getUsername())
                    .userRole(user.getUserRole())
                    .gender(user.getGender())
                    .avatar(user.getAvatar())
                    .phone(user.getPhone())
                    .email(user.getEmail())
                    .createTime(user.getCreateTime())
                    .biography(user.getBiography())
                    .myPublish(user.getMyPublish())
                    .myPraised(user.getMyPraised())
                    .myCollection(user.getMyCollection())
                    .myFollows(user.getMyFollows())
                    .myFans(user.getMyFans())
                    .myCoins(user.getMyCoins())
                    .tags(user.getTags())
                    .build();

            return Result.success(userVO);

        } catch (Exception e) {
            log.error("获取用户信息失败: {}", e.getMessage());
            return Result.failure(500, "获取用户信息失败: " + e.getMessage());
        }
    }

    /**
     * 关注用户
     * 
     * @param followerId 关注者ID
     * @param followedId 被关注者ID
     * @return 关注结果
     */
    @PostMapping("/follow/{followerId}/{followedId}")
    @Operation(summary = "关注用户")
    public Result<Boolean> followUser(@PathVariable Integer followerId, @PathVariable Integer followedId) {
        try {
            if (followerId == null || followerId <= 0) {
                return Result.failure(400, "关注者ID不合法");
            }
            if (followedId == null || followedId <= 0) {
                return Result.failure(400, "被关注者ID不合法");
            }
            if (followerId.equals(followedId)) {
                return Result.failure(400, "不能关注自己");
            }

            boolean success = userService.followUser(followerId, followedId);
            return Result.success(success);
        } catch (IllegalArgumentException e) {
            log.error("关注用户参数错误: {}", e.getMessage());
            return Result.failure(400, e.getMessage());
        } catch (Exception e) {
            log.error("关注用户失败", e);
            return Result.failure(500, "关注用户失败: " + e.getMessage());
        }
    }

    /**
     * 获取用户关注列表
     * 
     * @param userId 用户ID
     * @return 关注列表
     */
    @GetMapping("/follows/{userId}")
    @Operation(summary = "获取用户关注列表")
    public Result<List<UserVO>> getUserFollowList(@PathVariable Integer userId) {
        try {
            if (userId == null || userId <= 0) {
                return Result.failure(400, "用户ID不合法");
            }

            List<UserVO> followList = userService.getUserFollowList(userId);
            return Result.success(followList);
        } catch (Exception e) {
            log.error("获取关注列表失败", e);
            return Result.failure(500, "获取关注列表失败: " + e.getMessage());
        }
    }

    /**
     * 获取用户粉丝列表
     * 
     * @param userId 用户ID
     * @return 粉丝列表
     */
    @GetMapping("/fans/{userId}")
    @Operation(summary = "获取用户粉丝列表")
    public Result<List<UserVO>> getUserFansList(@PathVariable Integer userId) {
        try {
            if (userId == null || userId <= 0) {
                return Result.failure(400, "用户ID不合法");
            }

            List<UserVO> fansList = userService.getUserFansList(userId);
            return Result.success(fansList);
        } catch (Exception e) {
            log.error("获取粉丝列表失败", e);
            return Result.failure(500, "获取粉丝列表失败: " + e.getMessage());
        }
    }

    /**
     * 取消关注用户
     * 
     * @param followerId 关注者ID
     * @param followedId 被关注者ID
     * @return 取消关注结果
     */
    @DeleteMapping("/follow/{followerId}/{followedId}")
    @Operation(summary = "取消关注用户")
    public Result<Boolean> unfollowUser(@PathVariable Integer followerId, @PathVariable Integer followedId) {
        try {
            if (followerId == null || followerId <= 0) {
                return Result.failure(400, "关注者ID不合法");
            }
            if (followedId == null || followedId <= 0) {
                return Result.failure(400, "被关注者ID不合法");
            }

            boolean success = userService.unfollowUser(followerId, followedId);
            return Result.success(success);
        } catch (IllegalArgumentException e) {
            log.error("取消关注用户参数错误: {}", e.getMessage());
            return Result.failure(400, e.getMessage());
        } catch (Exception e) {
            log.error("取消关注用户失败", e);
            return Result.failure(500, "取消关注用户失败: " + e.getMessage());
        }
    }

    /**
     * 检查关注状态
     * 
     * @param followerId 关注者ID
     * @param followedId 被关注者ID
     * @return 关注状态
     */
    @GetMapping("/follow/check/{followerId}/{followedId}")
    @Operation(summary = "检查关注状态")
    public Result<Boolean> checkFollowStatus(@PathVariable Integer followerId, @PathVariable Integer followedId) {
        try {
            if (followerId == null || followerId <= 0) {
                return Result.failure(400, "关注者ID不合法");
            }
            if (followedId == null || followedId <= 0) {
                return Result.failure(400, "被关注者ID不合法");
            }
            if (followerId.equals(followedId)) {
                // 自己不能关注自己
                return Result.success(false);
            }

            boolean isFollowing = userService.checkFollowStatus(followerId, followedId);
            return Result.success(isFollowing);
        } catch (IllegalArgumentException e) {
            log.error("检查关注状态参数错误: {}", e.getMessage());
            return Result.failure(400, e.getMessage());
        } catch (Exception e) {
            log.error("检查关注状态失败", e);
            return Result.failure(500, "检查关注状态失败: " + e.getMessage());
        }
    }

    /**
     * 更新用户标签
     * 
     * @param updateUserTagsDTO 包含用户ID和标签的DTO
     * @return 更新结果
     */
    @PostMapping("/updateTags")
    @Operation(summary = "更新用户标签")
    public Result<Boolean> updateUserTags(@RequestBody UpdateUserTagsDTO updateUserTagsDTO) {
        try {
            if (updateUserTagsDTO == null) {
                return Result.failure(400, "请求参数不能为空");
            }

            Integer userId = updateUserTagsDTO.getUserId();
            List<String> tags = updateUserTagsDTO.getTags();

            if (userId == null || userId <= 0) {
                return Result.failure(400, "用户ID不合法");
            }

            if (tags == null) {
                return Result.failure(400, "标签不能为空");
            }

            // 检查标签数量限制
            if (tags.size() > 5) {
                return Result.failure(400, "标签数量不能超过5个");
            }

            // 调用服务层方法更新用户标签
            boolean success = userService.updateUserTags(userId, tags);
            return Result.success(success);
        } catch (Exception e) {
            log.error("更新用户标签失败", e);
            return Result.failure(500, "更新用户标签失败: " + e.getMessage());
        }
    }

    /**
     * 重置密码
     * 
     * @param resetPasswordDTO 重置密码信息
     * @return 重置结果
     */
    @PostMapping("/resetPassword")
    @Operation(summary = "重置密码")
    public Result<Boolean> resetPassword(@RequestBody ResetPasswordDTO resetPasswordDTO) {
        if (resetPasswordDTO == null) {
            return Result.failure(400, "请求参数不能为空");
        }

        String email = resetPasswordDTO.getEmail();
        String captcha = resetPasswordDTO.getCaptcha();
        String newPassword = resetPasswordDTO.getNewPassword();
        String checkPassword = resetPasswordDTO.getCheckPassword();

        // 参数校验
        if (StringUtils.isAllBlank(email, captcha, newPassword, checkPassword)) {
            return Result.failure(400, "请求参数不完整");
        }

        // 校验密码长度
        if (newPassword.length() < 8 || checkPassword.length() < 8) {
            return Result.failure(400, "密码长度不得小于8位");
        }

        // 校验两次密码是否一致
        if (!newPassword.equals(checkPassword)) {
            return Result.failure(400, "两次输入的密码不一致");
        }

        // 校验验证码
        String redisKey = "email:code:" + email.toLowerCase();
        String storedCode = (String) redisTemplate.opsForValue().get(redisKey);
        if (storedCode == null) {
            return Result.failure(50001, "验证码已过期");
        }
        if (!storedCode.equals(captcha)) {
            return Result.failure(50001, "验证码错误");
        }

        try {
            // 调用服务层方法重置密码
            boolean success = userService.resetPasswordByEmail(email, newPassword);
            if (success) {
                // 删除验证码
                redisTemplate.delete(redisKey);
                return Result.success(true);
            } else {
                return Result.failure(404, "未找到与该邮箱关联的账号");
            }
        } catch (Exception e) {
            log.error("重置密码失败", e);
            return Result.failure(500, "重置密码失败: " + e.getMessage());
        }
    }

    /**
     * 增加用户货币
     * 
     * @param userId 用户ID
     * @param coins 增加的货币数量
     * @return 增加结果
     */
    @PostMapping("/addCoins")
    @Operation(summary = "增加用户货币")
    public Result<Boolean> addUserCoins(@RequestParam Integer userId, @RequestParam Integer coins) {
        boolean success = userService.addUserCoins(userId, coins);
        if (success) {
            return Result.success(true);
        } else {
            return Result.failure(500, "增加货币失败");
        }
    }
}
